package org.budo.warehouse.web.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.budo.support.dao.page.Page;
import org.budo.support.dao.page.PageModel;
import org.budo.support.java.net.util.JavaNetUtil;
import org.budo.support.javax.sql.util.JdbcUtil;
import org.budo.support.lang.util.MapUtil;
import org.budo.warehouse.logic.api.IDataNodeLogic;
import org.budo.warehouse.service.api.IDataNodeService;
import org.budo.warehouse.service.entity.DataNode;
import org.budo.warehouse.web.api.DataNodeApi;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

/**
 * @author limingwei
 */
@Slf4j
@Component
public class DataNodeApiImpl implements DataNodeApi {
    @Resource
    private IDataNodeService dataNodeService;

    @Resource
    private IDataNodeLogic dataNodeLogic;

    @Override
    public PageModel<DataNode> list(Page page) {
        return dataNodeService.list(page);
    }

    @Override
    public List<String> listNameByIds(List<Integer> ids) {
        return dataNodeService.listNameByIds(ids);
    }

    @Override
    public DataNode findById(Integer id) {
        DataNode dataNode = dataNodeService.findById(id);
        if (null == dataNode) {
            return null;
        }

        dataNode.setPassword(null);
        return dataNode;
    }

    @Override
    public Integer insertIgnoreNull(DataNode dataNode) {
        return dataNodeService.insertIgnoreNull(dataNode);
    }

    @Override
    public Boolean updateIgnoreNull(DataNode dataNode) {
        return dataNodeService.updateIgnoreNull(dataNode);
    }

    @Override
    public List<Map<String, Object>> showGrants() {
        List<DataNode> dataNodes = dataNodeService.listMysqlNodes(Page.max());

        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        for (DataNode dataNode : dataNodes) {
            String grants = dataNodeLogic.showGrants(dataNode);

            Map<String, Object> grantsMap = MapUtil.stringObjectMap("dataNodeId", dataNode.getId(), //
                    "url", dataNode.getUrl(), //
                    "username", dataNode.getUsername(), //
                    "grants", grants);
            list.add(grantsMap);
        }

        return list;
    }

    @Override
    public String checkDataNode(Integer id) {
        DataNode dataNode = dataNodeService.findById(id);
        if (null == dataNode) {
            return "DataNode#" + id + " not found";
        }

        String host = JdbcUtil.getHost(dataNode.getUrl());
        Integer port = JdbcUtil.getPort(dataNode.getUrl());
        port = null == port ? 3306 : port;

        // 检查端口是否可用
        if (!JavaNetUtil.isPortUsing(host, port, 2000)) {
            log.error("#109 canalDataProducer return, host=" + host + ", port=" + port + ", url=" + dataNode.getUrl() + ", dataNode.id=" + dataNode.getId());
            return "port not ok";
        }

        return "port ok";
    }
}